package org.medusa.buffer;

public class BufferUtil {
	
	// Int16
	/*
	public static void Int16ToBytes(byte[] dst, short val, int offset) {
		dst[offset + 1] = (byte) (val >>> 8);
		dst[offset + 0] = (byte) (val);
	}

	public static short BytesToInt16(byte[] src, int offset) {
		short accum = 0;

		accum |= (src[offset + 1] & 0xff) << 8;
		accum |= (src[offset + 0] & 0xff);

		return accum;
	}*/

	// Int16
	public static void Int16ToByteBuffer(Buffer dst, short val) {
		dst.WriteInt8((byte) val);
		dst.WriteInt8((byte) (val >>> 8));
	}

	public static short ByteBufferToInt16(Buffer src) {
		short accum = 0;

		accum |= (src.ReadInt8() & 0xff);
		accum |= (src.ReadInt8() & 0xff) << 8;

		return accum;
	}

	// Int32
	/*
	public static void Int32ToBytes(byte[] dst, int val, int offset) {
		dst[offset + 3] = (byte) (val >>> 24);// 取最高8位放到0下标
		dst[offset + 2] = (byte) (val >>> 16);// 取次高8为放到1下标
		dst[offset + 1] = (byte) (val >>> 8); // 取次低8位放到2下标
		dst[offset + 0] = (byte) (val); // 取最低8位放到3下标
	}

	public static int BytesToInt32(byte[] src, int offset) {
		int accum = 0;

		accum |= (src[offset + 3] & 0xff) << 24;// &0xff将byte值无差异转成int,避免Java自动类型提升后,会保留高位的符号位
		accum |= (src[offset + 2] & 0xff) << 16;
		accum |= (src[offset + 1] & 0xff) << 8;
		accum |= (src[offset + 0] & 0xff);

		return accum;
	}*/

	// Int32
	public static void Int32ToByteBuffer(Buffer dst, int val) {
		dst.WriteInt8((byte) (val));
		dst.WriteInt8((byte) (val >>> 8));
		dst.WriteInt8((byte) (val >>> 16));
		dst.WriteInt8((byte) (val >>> 24));
	}

	public static int ByteBufferToInt32(Buffer src) {
		int accum = 0;

		accum |= (src.ReadInt8() & 0xff);
		accum |= (src.ReadInt8() & 0xff) << 8;
		accum |= (src.ReadInt8() & 0xff) << 16;
		accum |= (src.ReadInt8() & 0xff) << 24;

		return accum;
	}

	// Int64
	/*
	public static byte[] Int64ToBytes(byte[] dst, long val, int offset) {
		dst[offset + 7] = (byte) (val >>> 56);
		dst[offset + 6] = (byte) (val >>> 48);
		dst[offset + 5] = (byte) (val >>> 40);
		dst[offset + 4] = (byte) (val >>> 32);
		dst[offset + 3] = (byte) (val >>> 24);
		dst[offset + 2] = (byte) (val >>> 16);
		dst[offset + 1] = (byte) (val >>> 8);
		dst[offset + 0] = (byte) (val);

		return dst;
	}

	public static long BytesToInt64(byte[] src, int offset) {
		long accum = 0;

		accum |= (long) (src[offset + 7] & 0xff) << 56;
		accum |= (long) (src[offset + 6] & 0xff) << 48;
		accum |= (long) (src[offset + 5] & 0xff) << 40;
		accum |= (long) (src[offset + 4] & 0xff) << 32;
		accum |= (long) (src[offset + 3] & 0xff) << 24;
		accum |= (long) (src[offset + 2] & 0xff) << 16;
		accum |= (long) (src[offset + 1] & 0xff) << 8;
		accum |= (long) (src[offset + 0] & 0xff);

		return accum;
	}*/

	// Int64
	public static Buffer Int64ToByteBuffer(Buffer dst, long val) {
		dst.WriteInt8((byte) (val));
		dst.WriteInt8((byte) (val >>> 8));
		dst.WriteInt8((byte) (val >>> 16));
		dst.WriteInt8((byte) (val >>> 24));
		dst.WriteInt8((byte) (val >>> 32));
		dst.WriteInt8((byte) (val >>> 40));
		dst.WriteInt8((byte) (val >>> 48));
		dst.WriteInt8((byte) (val >>> 56));

		return dst;
	}

	public static long ByteBufferToInt64(Buffer src) {
		long accum = 0;

		accum |= (long) (src.ReadInt8() & 0xff);
		accum |= (long) (src.ReadInt8() & 0xff) << 8;
		accum |= (long) (src.ReadInt8() & 0xff) << 16;
		accum |= (long) (src.ReadInt8() & 0xff) << 24;
		accum |= (long) (src.ReadInt8() & 0xff) << 32;
		accum |= (long) (src.ReadInt8() & 0xff) << 40;
		accum |= (long) (src.ReadInt8() & 0xff) << 48;
		accum |= (long) (src.ReadInt8() & 0xff) << 56;

		return accum;
	}

	// Float32
	/*
	static void Float32ToBytes(byte[] dst, float val, int offset) {
		int accum = Float.floatToRawIntBits(val);

		dst[offset + 0] = (byte) ((accum >> 24) & 0xFF);
		dst[offset + 1] = (byte) ((accum >> 16) & 0xFF);
		dst[offset + 2] = (byte) ((accum >> 8) & 0xFF);
		dst[offset + 3] = (byte) (accum & 0xFF);
	}

	static float BytesToFloat32(byte[] src, int offse) {
		int accum = 0;

		accum |= (int) (src[offse + 0] & 0xFF) << 24;
		accum |= (int) (src[offse + 1] & 0xFF) << 16;
		accum |= (int) (src[offse + 2] & 0xFF) << 8;
		accum |= (int) (src[offse + 3] & 0xFF);
		
		return Float.intBitsToFloat(accum);
	}*/

	// Float32
	static void Float32ToByteBuffer(Buffer dst, float val) {
		int accum = Float.floatToRawIntBits(val);

		dst.WriteInt8((byte) ((accum >> 24) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 16) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 8) & 0xFF));
		dst.WriteInt8((byte) ((accum) & 0xFF));
	}

	static float ByteBufferToFloat32(Buffer src) {
		int accum = 0;

		accum |= (int) (src.ReadInt8() & 0xFF) << 24;
		accum |= (int) (src.ReadInt8() & 0xFF) << 16;
		accum |= (int) (src.ReadInt8() & 0xFF) << 8;
		accum |= (int) (src.ReadInt8() & 0xFF);
		
		return Float.intBitsToFloat(accum);
	}

	// Float64
	/*
	static void Float64ToBytes(byte[] dst, double val, int offset) {
		long accum = Double.doubleToRawLongBits(val);

		dst[offset + 0] = (byte) ((accum >> 56) & 0xFF);
		dst[offset + 1] = (byte) ((accum >> 48) & 0xFF);
		dst[offset + 2] = (byte) ((accum >> 40) & 0xFF);
		dst[offset + 3] = (byte) ((accum >> 32) & 0xFF);
		dst[offset + 4] = (byte) ((accum >> 24) & 0xFF);
		dst[offset + 5] = (byte) ((accum >> 16) & 0xFF);
		dst[offset + 6] = (byte) ((accum >> 8) & 0xFF);
		dst[offset + 7] = (byte) (accum & 0xFF);
	}

	static double BytesToFloat64(byte[] src, int offset) {
		long accum = 0;

		accum |= (long) (src[offset + 0] & 0xFF) << 56;
		accum |= (long) (src[offset + 1] & 0xFF) << 48;
		accum |= (long) (src[offset + 2] & 0xFF) << 40;
		accum |= (long) (src[offset + 3] & 0xFF) << 32;
		accum |= (long) (src[offset + 4] & 0xFF) << 24;
		accum |= (long) (src[offset + 5] & 0xFF) << 16;
		accum |= (long) (src[offset + 6] & 0xFF) << 8;
		accum |= (long) (src[offset + 7] & 0xFF);
		
		return Double.longBitsToDouble(accum);
	}*/

	// Float64
	static void Float64ToByteBuffer(Buffer dst, double val) {
		long accum = Double.doubleToRawLongBits(val);

		dst.WriteInt8((byte) ((accum >> 56) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 48) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 40) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 32) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 24) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 16) & 0xFF));
		dst.WriteInt8((byte) ((accum >> 8) & 0xFF));
		dst.WriteInt8((byte) ((accum) & 0xFF));
	}

	static double ByteBufferToFloat64(Buffer src) {
		long accum = 0;

		accum |= (long) (src.ReadInt8() & 0xFF) << 56;
		accum |= (long) (src.ReadInt8() & 0xFF) << 48;
		accum |= (long) (src.ReadInt8() & 0xFF) << 40;
		accum |= (long) (src.ReadInt8() & 0xFF) << 32;
		accum |= (long) (src.ReadInt8() & 0xFF) << 24;
		accum |= (long) (src.ReadInt8() & 0xFF) << 16;
		accum |= (long) (src.ReadInt8() & 0xFF) << 8;
		accum |= (long) (src.ReadInt8() & 0xFF);

		return Double.longBitsToDouble(accum);
	}

}
